#include <stdio.h>
#include <stdlib.h>
#include <math.h>

// 函数声明
void read_txt_data(const char *filename, const int n, double array[1][n]);
void matrix_mul(const int n_rows, const int n_cols, const int p, 
                const double matrix1[n_rows][p], 
                const double matrix2[p][n_cols], 
                double matrix_product[n_rows][n_cols]);
void add_matrices(const int n_rows, const int n_cols, 
                  const double mat1[n_rows][n_cols], 
                  const double mat2[n_rows][n_cols], 
                  double result[n_rows][n_cols]);
void activate_function(const int SIZE, const double F[1][SIZE], double G[1][SIZE]);

// 第一隐藏层逻辑函数
void first_hidden_layer(const double input[1][784], const char *weight_file, 
                        const char *bias_file, double output[1][128]) {
    // 临时变量
    double weights[784][128];   // 权重矩阵
    double biases[1][128];      // 偏置矩阵
    double intermediate[1][128]; // 中间结果矩阵

    // 1. 从文件中读取权重并重塑为 784×128 矩阵
    double weights_flat[1][784 * 128];
    read_txt_data(weight_file, 784 * 128, weights_flat);
    for (int i = 0; i < 784; i++) {
        for (int j = 0; j < 128; j++) {
            weights[i][j] = weights_flat[0][i * 128 + j];
        }
    }

    // 2. 矩阵乘法：输入矩阵 (1×784) × 权重矩阵 (784×128) = 中间矩阵 (1×128)
    matrix_mul(1, 128, 784, input, weights, intermediate);

    // 3. 从文件中读取偏置 (1×128)
    read_txt_data(bias_file, 128, biases);

    // 4. 矩阵加法：中间矩阵 (1×128) + 偏置矩阵 (1×128) = 激活前矩阵 (1×128)
    double activated_input[1][128];
    add_matrices(1, 128, intermediate, biases, activated_input);

    // 5. ReLU 激活函数
    activate_function(128, activated_input, output);
}

// 读取文本文件数据到矩阵
void read_txt_data(const char *filename, const int n, double array[1][n]) {
    FILE *file = fopen(filename, "r");
    if (!file) {
        printf("Error: Cannot open file %s\n", filename);
        exit(EXIT_FAILURE);
    }
    for (int i = 0; i < n; i++) {
        fscanf(file, "%lf", &array[0][i]);
    }
    fclose(file);
}

// 矩阵乘法
void matrix_mul(const int n_rows, const int n_cols, const int p, 
                const double matrix1[n_rows][p], 
                const double matrix2[p][n_cols], 
                double matrix_product[n_rows][n_cols]) {
    for (int i = 0; i < n_rows; i++) {
        for (int j = 0; j < n_cols; j++) {
            matrix_product[i][j] = 0.0;
            for (int k = 0; k < p; k++) {
                matrix_product[i][j] += matrix1[i][k] * matrix2[k][j];
            }
        }
    }
}

// 矩阵加法
void add_matrices(const int n_rows, const int n_cols, 
                  const double mat1[n_rows][n_cols], 
                  const double mat2[n_rows][n_cols], 
                  double result[n_rows][n_cols]) {
    for (int i = 0; i < n_rows; i++) {
        for (int j = 0; j < n_cols; j++) {
            result[i][j] = mat1[i][j] + mat2[i][j];
        }
    }
}

// ReLU 激活函数
void activate_function(const int SIZE, const double F[1][SIZE], double G[1][SIZE]) {
    for (int i = 0; i < SIZE; i++) {
        G[0][i] = fmax(F[0][i], 0.0);
    }
    fclose(file);
    *size = count; // 返回读取的值的数量
    return count;
}

int main() {
    double *weights = NULL;
    double *biases = NULL;

    int weight_count = 0;
    int bias_count = 0;

    // 文件路径（用户需要自行修改为实际路径）
    const char *weights_file = " input_files/W1.txt";
    const char *biases_file = "input_files/B1.txt";

    // 读取权重文件
    printf("读取权重文件：%s\n", weights_file);
    if (read_file(weights_file, &weights, &weight_count) > 0) {
        printf("已读取 %d 个权重值：\n", weight_count);
        for (int i = 0; i < weight_count; i++) {
            printf("%.6f ", weights[i]);
        }
        printf("\n");
    }

    // 读取偏置文件
    printf("读取偏置文件：%s\n", biases_file);
    if (read_file(biases_file, &biases, &bias_count) > 0) {
        printf("已读取 %d 个偏置值：\n", bias_count);
        for (int i = 0; i < bias_count; i++) {
            printf("%.6f ", biases[i]);
        }
        printf("\n");
    }

    // 释放动态分配的内存
    free(weights);
    free(biases);

    return 0;
}